class JtlAnalyzer {
    constructor(data) {
        this.data = data;
        this.report = [];
    }

    analyze() {
        const baseReport = this._getReport().find(row => row.label === "主流程");
        const report = this._getReport().filter(row => row.type === "GROUP" || row.type === "TOTAL");
        const apis = this._getReport().filter(row => row.type === "HTTP_REQUEST")
            .sort((a, b) => b.averageResponseTime - a.averageResponseTime);;
        return { baseReport, report, apis };
    }

    _getReport() {
        const report = this.data && Object.keys(this.data).map(label => {
            const data = this.data[label];
            const averageResponseTime = data.requestCount > 0 ? data.totalResponseTime / data.requestCount : 0;
            const elapsedTimeInSeconds = (data.maxTimeStamp - data.minTimeStamp) / 1000;

            // 响应时间波动率(%)
            let sumOfSquaredDifferences = 0;
            for (const time of data.responseTimes) {
                const difference = time - averageResponseTime;
                sumOfSquaredDifferences += difference * difference;
            }
            const variance = data.requestCount > 1 ? sumOfSquaredDifferences / (data.requestCount - 1) : 0;
            const standardDeviation = Math.sqrt(variance);
            const responseTimeVolatility = averageResponseTime > 0 ? (standardDeviation / averageResponseTime) * 100 : 0;

            // 实际吞吐量(请求数/秒)
            const actualThroughput = elapsedTimeInSeconds > 0 ? data.successfulRequestCount / elapsedTimeInSeconds : 0;

            // 理论吞吐量(请求数/秒)
            const theoreticalThroughput = averageResponseTime > 0 ? data.maxAllThreads / (averageResponseTime / 1000) : 0;

            // 错误率(%)
            const errorRate = data.requestCount > 0 ? (data.failedRequestCount / data.requestCount) * 100 : 0;

            // 发送和接收数据速率(KB/s)
            const sendRate = elapsedTimeInSeconds > 0 ? (data.totalSentBytes / 1024) / elapsedTimeInSeconds : 0;
            const receiveRate = elapsedTimeInSeconds > 0 ? (data.totalReceivedBytes / 1024) / elapsedTimeInSeconds : 0;

            // 计算90%Line
            const sortedResponseTimes = data.responseTimes.slice().sort((a, b) => a - b);
            const index = Math.ceil(0.9 * sortedResponseTimes.length) - 1;
            const ninetyPercentLine = sortedResponseTimes.length > 0 ? sortedResponseTimes[index] : 0;

            return {
                label: label,
                threads: data.maxAllThreads,
                samples: data.requestCount,
                averageResponseTime: parseFloat(averageResponseTime.toFixed(5)),
                minResponseTime: parseFloat(data.minResponseTime.toFixed(5)),
                maxResponseTime: parseFloat(data.maxResponseTime.toFixed(5)),
                ninetyPercentLine: parseFloat(ninetyPercentLine.toFixed(5)),
                responseTimeVolatility: parseFloat(responseTimeVolatility.toFixed(5)),
                actualThroughput: parseFloat(actualThroughput.toFixed(5)),
                theoreticalThroughput: parseFloat(theoreticalThroughput.toFixed(5)),
                errorRate: parseFloat(errorRate.toFixed(5)),
                sendRate: parseFloat(sendRate.toFixed(5)),
                receiveRate: parseFloat(receiveRate.toFixed(5)),
                type: data.type,
                minTimeStamp: data.minTimeStamp,
                maxTimeStamp: data.maxTimeStamp
            };
        });

        // TOTAL
        const groupReport = report.filter(row => row.type === "GROUP");
        let totalSamples = 0;
        let totalResponseTime = 0;
        let totalSuccessfulRequestCount = 0;
        let totalFailedRequestCount = 0;
        let totalSentBytes = 0;
        let totalReceivedBytes = 0;
        let minTimeStamp = Infinity;
        let maxTimeStamp = -Infinity;
        let totalThreads = 0;
        let allResponseTimes = [];

        groupReport.forEach(row => {
            totalSamples += row.samples;
            totalResponseTime += row.averageResponseTime * row.samples;
            totalSuccessfulRequestCount += row.samples * (1 - row.errorRate / 100);
            totalFailedRequestCount += row.samples * (row.errorRate / 100);
            const elapsedTimeInSeconds = (row.maxTimeStamp - row.minTimeStamp) / 1000;
            totalSentBytes += row.sendRate * elapsedTimeInSeconds * 1024;
            totalReceivedBytes += row.receiveRate * elapsedTimeInSeconds * 1024;
            minTimeStamp = Math.min(minTimeStamp, row.minTimeStamp);
            maxTimeStamp = Math.max(maxTimeStamp, row.maxTimeStamp);
            totalThreads += row.threads;
            // 合并所有响应时间
            for (let i = 0; i < row.samples; i++) {
                allResponseTimes.push(row.averageResponseTime);
            }
        });

        const totalAverageResponseTime = totalSamples > 0 ? totalResponseTime / totalSamples : 0;
        const totalElapsedTimeInSeconds = (maxTimeStamp - minTimeStamp) / 1000;
        // 响应时间波动率(%)
        let totalSumOfSquaredDifferences = 0;
        groupReport.forEach(row => {
            const difference = row.averageResponseTime - totalAverageResponseTime;
            totalSumOfSquaredDifferences += difference * difference * row.samples;
        });
        const totalVariance = totalSamples > 1 ? totalSumOfSquaredDifferences / (totalSamples - 1) : 0;
        const totalStandardDeviation = Math.sqrt(totalVariance);
        const totalResponseTimeVolatility = totalAverageResponseTime > 0 ? (totalStandardDeviation / totalAverageResponseTime) * 100 : 0;

        // 实际吞吐量(请求数/秒)
        const totalActualThroughput = totalElapsedTimeInSeconds > 0 ? totalSuccessfulRequestCount / totalElapsedTimeInSeconds : 0;

        // 理论吞吐量(请求数/秒)
        const totalTheoreticalThroughput = totalAverageResponseTime > 0 ? totalThreads / (totalAverageResponseTime / 1000) : 0;

        // 错误率(%)
        const totalErrorRate = totalSamples > 0 ? (totalFailedRequestCount / totalSamples) * 100 : 0;

        // 发送和接收数据速率(KB/s)
        const totalSendRate = totalElapsedTimeInSeconds > 0 ? (totalSentBytes / 1024) / totalElapsedTimeInSeconds : 0;
        const totalReceiveRate = totalElapsedTimeInSeconds > 0 ? (totalReceivedBytes / 1024) / totalElapsedTimeInSeconds : 0;

        // 计算Total的90%Line
        const sortedAllResponseTimes = allResponseTimes.slice().sort((a, b) => a - b);
        const totalIndex = Math.ceil(0.9 * sortedAllResponseTimes.length) - 1;
        const totalNinetyPercentLine = sortedAllResponseTimes.length > 0 ? sortedAllResponseTimes[totalIndex] : 0;

        const totalRow = {
            label: "Total",
            threads: totalThreads,
            samples: totalSamples,
            averageResponseTime: parseFloat(totalAverageResponseTime.toFixed(5)),
            minResponseTime: Math.min(...groupReport.map(row => row.minResponseTime)),
            maxResponseTime: Math.max(...groupReport.map(row => row.maxResponseTime)),
            ninetyPercentLine: parseFloat(totalNinetyPercentLine.toFixed(5)),
            responseTimeVolatility: parseFloat(totalResponseTimeVolatility.toFixed(5)),
            actualThroughput: parseFloat(totalActualThroughput.toFixed(5)),
            theoreticalThroughput: parseFloat(totalTheoreticalThroughput.toFixed(5)),
            errorRate: parseFloat(totalErrorRate.toFixed(5)),
            sendRate: parseFloat(totalSendRate.toFixed(5)),
            receiveRate: parseFloat(totalReceiveRate.toFixed(5)),
            type: "TOTAL"
        };

        report.push(totalRow);
        return report;
    }
}

module.exports = JtlAnalyzer;